﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;

using CoreLib;

namespace JSZJCoordinateAdjustmentSys
{
    public partial class FrmCoordinateAdjSys : Form
    {

        /// <summary>
        /// 原始碎部文件点
        /// </summary>
        private string sourceFileName = "";

        private List<string> SourceList = new List<string>();
 
        public FrmCoordinateAdjSys()
        {
            InitializeComponent();
        }

        private void btnSelSourceFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "二进制文件(*.dat;*.asc;*.txt)|*.dat;*.asc;*.txt";
            ofd.FilterIndex = 1;
            ofd.RestoreDirectory = true;
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                sourceFileName = ofd.FileName;
                txtSourceFile.Text = sourceFileName;
                SourceList = ReadTopoFileClass.ReadSSSTopoFile(sourceFileName);

                //添加到listview中
                foreach (string str in SourceList)
                {
                    ListViewItem item = new ListViewItem();
                    string[] tmp = str.Split(',');
                    item.Text = tmp[0];
                    item.SubItems.Add(tmp[1] + "," + tmp[2]);
                    item.SubItems.Add("");

                    listViewSourceData.Items.Add(item);
                }

            }
        }

        private void numericUpDownSZX_ValueChanged(object sender, EventArgs e)
        {
            if (numericUpDownSZY.Value >= 0)
            {
                txtSZXY.Text = numericUpDownSZX.Value + "," + numericUpDownSZY.Value;
            }
        }

        private void numericUpDownSZY_ValueChanged(object sender, EventArgs e)
        {
            if (numericUpDownSZX.Value>=0)
            {
                txtSZXY.Text = numericUpDownSZX.Value + "," + numericUpDownSZY.Value;
            }
        }

        private void txtSZXY_TextChanged(object sender, EventArgs e)
        {
        }

        private void txtSZXY_Leave(object sender, EventArgs e)
        {
            try
            {
                if (txtSZXY.Text != "")
                {
                    string[] tmp = txtSZXY.Text.Split(',');
                    double x = Convert.ToDouble(tmp[0]);
                    double y = Convert.ToDouble(tmp[1]);

                    numericUpDownSZX.Value = Convert.ToDecimal(x);
                    numericUpDownSZY.Value = Convert.ToDecimal(y);
                }
            }
            catch
            {
                txtSZXY.Text = "";
            }
        }

        private void numericUpDownDXX_ValueChanged(object sender, EventArgs e)
        {
            if (numericUpDownDXY.Value >= 0)
            {
                txtDXXY.Text = numericUpDownDXX.Value + "," + numericUpDownDXY.Value;
            }
        }

        private void numericUpDownDXY_ValueChanged(object sender, EventArgs e)
        {
            if(numericUpDownDXX.Value>=0)
            {
                txtDXXY.Text = numericUpDownDXX.Value + "," + numericUpDownDXY.Value;
            }
        }

        private void txtDXXY_Leave(object sender, EventArgs e)
        {
            try
            {
                if (txtDXXY.Text != "")
                {
                    string[] tmp = txtDXXY.Text.Split(',');
                    double x = Convert.ToDouble(tmp[0]);
                    double y = Convert.ToDouble(tmp[1]);

                    numericUpDownDXX.Value = Convert.ToDecimal(x);
                    numericUpDownDXY.Value = Convert.ToDecimal(y);
                }
            }
            catch
            {
                txtDXXY.Text = "";
            }
        }

        private void ToolStripMenuItemSetAsSZD_Click(object sender, EventArgs e)
        {
            //设置为设站点
            if(listViewSourceData.SelectedIndices.Count>0)
            {
                ClearItemState(listViewSourceData, "设站点");
                ListViewItem selItem = listViewSourceData.SelectedItems[0];
                selItem.SubItems[2].Text = "设站点";
            }
        }

        private void ToolStripMenuItemSetAsDXD_Click(object sender, EventArgs e)
        {
            //设置为定向点
            if (listViewSourceData.SelectedIndices.Count > 0)
            {
                ClearItemState(listViewSourceData, "定向点");
                ListViewItem selItem = listViewSourceData.SelectedItems[0];
                selItem.SubItems[2].Text = "定向点";
            }
        }

        /// <summary>
        /// 清除状态
        /// </summary>
        /// <param name="list"></param>
        /// <param name="state"></param>
        private void ClearItemState(ListView list, string state)
        {
            foreach (ListViewItem item in list.Items)
            {
                if (item.SubItems[2].Text == state)
                {
                    item.SubItems[2].Text = "";
                }
            }
        }

        private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
        {
            if (listViewSourceData.SelectedIndices.Count != 1)
            {
                e.Cancel = true;
            }
        }

        private void btnExprotAll_Click(object sender, EventArgs e)
        {
            //导出所有
            try
            {
                List<string> newData = new List<string>();
                if (txtDXXY.Text != "" && txtSZXY.Text != "")
                {
                    if (!IsSelSZDX(listViewSourceData))
                    {
                        MessageBox.Show("请选择测量文件中设站点、定向点", "信息提示");
                        return;
                    }

                    SaveFileDialog sfd = new SaveFileDialog();
                    sfd.Filter = " DAT files(*.dat)|*.dat|ASC files(*.asc)|*.asc|Txt files(*.txt)|*.txt";
                    sfd.FilterIndex = 1;
                    if (sourceFileName != "")
                    {
                        string sourceFilePath = Path.GetFullPath(sourceFileName);
                        sfd.InitialDirectory = sourceFilePath;
                        sfd.FileName = Path.GetFileNameWithoutExtension(sourceFileName) + "_transferred" + Path.GetExtension(sourceFileName);
                    }
                    sfd.RestoreDirectory = true;
                    if (sfd.ShowDialog() == DialogResult.OK)
                    {
                        //控制点
                        Point3D kz_szXY = new Point3D(Convert.ToDouble(numericUpDownSZX.Value), Convert.ToDouble(numericUpDownSZY.Value));

                        Point3D kz_dxXY = new Point3D(Convert.ToDouble(numericUpDownDXX.Value), Convert.ToDouble(numericUpDownDXY.Value));
                        //碎部点
                        Point3D szXY = GetSDDXY(listViewSourceData);
                        Point3D dxXY = GetDXDXY(listViewSourceData);

                        //求控制点方位角（弧度）
                        // double kz_Alfa = Math.Atan((kz_dxXY.Y - kz_szXY.Y) / (kz_dxXY.X - kz_szXY.X));
                        double kz_Alfa = Math.Atan2(kz_dxXY.Y - kz_szXY.Y, kz_dxXY.X - kz_szXY.X);
                        MessageBox.Show((kz_Alfa * 180 / Math.PI).ToString());

                        //求碎部点定向方位角（弧度）
                        //double sb_Alfa = Math.Atan((dxXY.Y - szXY.Y) / (dxXY.X - szXY.X));
                        double sb_Alfa = Math.Atan2(dxXY.Y - szXY.Y, dxXY.X - szXY.X);
                        MessageBox.Show((sb_Alfa * 180 / Math.PI).ToString());

                        double delt_Alfa = kz_Alfa - sb_Alfa;
                        MessageBox.Show((delt_Alfa * 180 / Math.PI).ToString());

                        //旋转矩阵
                        //double[,] R = { { Math.Cos(delt_Alfa), -Math.Sin(delt_Alfa) }, { Math.Sin(delt_Alfa), Math.Cos(delt_Alfa) } };

                        Point3D T = new Point3D(kz_szXY.X - szXY.X, kz_szXY.Y - szXY.Y);
                        foreach (string str in SourceList)
                        {
                            ListViewItem item = new ListViewItem();
                            string[] tmp = str.Split(',');

                            Point3D tmpXY = new Point3D(Convert.ToDouble(tmp[1]) + T.X, Convert.ToDouble(tmp[2]) + T.Y);

                            Point3D newXY = CalNewXY(kz_szXY, delt_Alfa, tmpXY, T);

                            string tmpNewXY = tmp[0] + "," + newXY.X + "," + newXY.Y;
                            newData.Add(tmpNewXY);
                        }
                        //将数据写入文件中
                        SaveFileClass.SaveASCIIFile(sfd.FileName, newData);
                    }// end of showdialog
                }//end of "txtDXXY.Text != "" && txtSZXY.Text != """
                else
                {
                    MessageBox.Show("请输入设站控制点与定向控制点坐标", "信息提示");
                    
                }
            }//end of try
            catch
            { }
            
        }

        private void btnExprotSelection_Click(object sender, EventArgs e)
        {
            //导出所选项
        }

        private void btnMapShow_Click(object sender, EventArgs e)
        {
            //地图显示 //413, 439
            if (btnMapShow.Text.Contains("地图显示"))
            {
                this.Size = new Size(800, 439);
                btnMapShow.Text = "<<地图隐藏";
            }
            else if (btnMapShow.Text.Contains("地图隐藏"))
            {
                this.Size = new Size(413, 439);
                btnMapShow.Text = "地图显示>>";
            }
        }

        /// <summary>
        /// 获取定向点XY
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        private Point3D GetDXDXY(ListView list)
        {
            Point3D rtn = new Point3D();
            foreach (ListViewItem item in list.Items)
            {
                if (item.SubItems[2].Text == "定向点")
                {
                    string[] tmp = item.SubItems[1].Text.Split(',');
                    rtn.X = Convert.ToDouble(tmp[0]);
                    rtn.Y = Convert.ToDouble(tmp[1]);
                }
            }
            return rtn;
        }

        /// <summary>
        /// 获取设站点XY
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        private Point3D GetSDDXY(ListView list)
        {
            Point3D rtn = new Point3D();
            foreach (ListViewItem item in list.Items)
            {
                if (item.SubItems[2].Text == "设站点")
                {
                    string[] tmp = item.SubItems[1].Text.Split(',');
                    rtn.X = Convert.ToDouble(tmp[0]);
                    rtn.Y = Convert.ToDouble(tmp[1]);
                }
            }
            return rtn;
        }

        /// <summary>
        /// 计算新坐标
        /// </summary>
        /// <param name="R"></param>
        /// <param name="T"></param>
        /// <param name="XY"></param>
        /// <param name="center">旋转中心</param>
        /// <returns></returns>
        private Point3D CalNewXY(Point3D o, double f_Angle, Point3D XY, Point3D T)
        {
            Point3D rtn = new Point3D();

            Point3D tmpXY = new Point3D();
            tmpXY.X = XY.X - o.X ;
            tmpXY.Y = XY.Y - o.Y;

            rtn.X = tmpXY.X * Math.Cos(f_Angle) - tmpXY.Y * Math.Sin(f_Angle) + o.X;
            rtn.Y = tmpXY.Y * Math.Cos(f_Angle) + tmpXY.X * Math.Sin(f_Angle) + o.Y;

            return rtn;
        }

        /// <summary>
        /// 判断时候已经选择定向点与设站点
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        private bool IsSelSZDX(ListView list)
        {
            bool rtn = false;
            bool rtn1 = false;
            bool rtn2 = false;
            foreach (ListViewItem item in list.Items)
            {
                if (item.SubItems[2].Text == "定向点")
                {
                    rtn1 = true;
                }

                if (item.SubItems[2].Text == "设站点")
                {
                    rtn2 = true;
                }
            }

            if (rtn1 == true && rtn2 == true)
            {
                rtn = true;
            }
            return rtn;
        }
    }
}
